package com.example.myweb.Service.Auth.Impl;

import com.example.myweb.Domain.Entity.ContentTopic;
import com.example.myweb.Domain.Entity.Topic;
import com.example.myweb.Dto.FeedItemDTO;
import com.example.myweb.Dto.TopicDTO;
import com.example.myweb.Exception.CustomException;
import com.example.myweb.Repository.JpaRepository.ContentTopicRepository;
import com.example.myweb.Repository.JpaRepository.FeedRepository;
import com.example.myweb.Repository.JpaRepository.TopicRepository;
import com.example.myweb.Service.Auth.TopicService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

@Service
public class TopicServiceImpl implements TopicService {

    @Autowired
    private TopicRepository topicRepository;

    @Autowired
    private ContentTopicRepository contentTopicRepository;

    @Autowired
    private FeedRepository feedRepository;

    @Override
    @Transactional
    public Set<Topic> findOrCreateTopics(List<String> topicNames) {
        if (topicNames == null || topicNames.isEmpty()) {
            return new HashSet<>();
        }

        Set<String> normalizedNames = topicNames.stream()
                .map(name -> name.trim().toLowerCase().replace("#", ""))
                .filter(name -> !name.isEmpty())
                .collect(Collectors.toSet());

        if (normalizedNames.isEmpty()) {
            return new HashSet<>();
        }

        Set<Topic> existingTopics = topicRepository.findByNameIn(new ArrayList<>(normalizedNames));

        Set<String> existingTopicNames = existingTopics.stream()
                .map(Topic::getName)
                .collect(Collectors.toSet());

        Set<String> newTopicNames = new HashSet<>(normalizedNames);
        newTopicNames.removeAll(existingTopicNames);

        List<Topic> newTopics = newTopicNames.stream().map(name -> {
            Topic topic = new Topic();
            topic.setName(name);
            return topic;
        }).collect(Collectors.toList());

        if (!newTopics.isEmpty()) {
            topicRepository.saveAll(newTopics);
        }

        Set<Topic> allTopics = new HashSet<>(existingTopics);
        allTopics.addAll(newTopics);

        return allTopics;
    }
    @Override
    @Transactional(readOnly = true)
    public List<TopicDTO> getHotTopics(int limit) {
        Pageable pageable = PageRequest.of(0, limit);
        List<Topic> hotTopics = topicRepository.findByOrderByHotScoreDesc(pageable);
        return hotTopics.stream()
                .map(topic -> new TopicDTO(topic.getTopicId(), topic.getName()))
                .collect(Collectors.toList());
    }

    @Override
    @Transactional(readOnly = true)
    public Page<FeedItemDTO> getContentByTopicName(String topicName, Pageable pageable) {
        // 1. 查找话题是否存在
        Topic topic = topicRepository.findByName(topicName.toLowerCase().trim())
                .orElseThrow(() -> new CustomException("话题不存在: " + topicName, HttpStatus.NOT_FOUND));

        // 2. 从关联表中分页查询出内容ID和类型
        Page<ContentTopic> contentTopicPage = contentTopicRepository.findByTopic(topic, pageable);

        // 3. 提取文章和动态的ID列表
        List<Long> articleIds = contentTopicPage.getContent().stream()
                .filter(ct -> ct.getContentType() == ContentTopic.ContentType.ARTICLE)
                .map(ContentTopic::getContentId)
                .collect(Collectors.toList());

        List<Long> dynamicIds = contentTopicPage.getContent().stream()
                .filter(ct -> ct.getContentType() == ContentTopic.ContentType.DYNAMIC)
                .map(ContentTopic::getContentId)
                .collect(Collectors.toList());

        // 4. 调用（可能需要新建的）FeedRepository方法来获取混合内容
        // 这里需要对FeedRepository进行扩展
        return feedRepository.findFeedByIds(articleIds, dynamicIds, pageable);
    }

    @Override
    @Transactional(readOnly = true)
    public List<TopicDTO> searchTopics(String keyword, int limit) {
        // 创建一个只关心数量限制的分页对象
        Pageable pageable = PageRequest.of(0, limit);

        List<Topic> topics = topicRepository.searchByNameContainingIgnoreCase(keyword, pageable);

        return topics.stream()
                .map(topic -> new TopicDTO(topic.getTopicId(), topic.getName()))
                .collect(Collectors.toList());
    }

    @Override
    @Transactional
    public void incrementTopicHotScore(Set<Topic> topics, int score) {
        if (topics == null || topics.isEmpty()) {
            return;
        }
        for (Topic topic : topics) {
            topic.setHotScore(topic.getHotScore() + score);
        }
        topicRepository.saveAll(topics);
    }
}